#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <alloc.h>
FILE *fAuthor;
void DisplayAuthorMenu();
void SearchByAuthorCode();
void SearchByAuthorName();
void AddAuthorRecord();
void AmendAuthorRecord();
bool SearchAuthor();
void DisplaySearchedAuthorRecord();
bool WriteNewAuthorRecord();

void LoadAuthorRecord(struct AuthorRefer **q);
void AddAuthorNode(struct AuthorRefer **q, int num);
void AssignAuthorRefer(struct AuthorRefer **p);

bool FindAuthorName();
void OpenAuthorFile();
void CloseAuthorFile();

/*========================define function upon=====================================================*/

int CurrAuthorRecNum=0;
int TotalAuthorNode=0;
char SearchedAuthorCode[7];
char SearchedAuthorName[21];
char purpose[25];
/*==============================Declare structure=============================*/
struct Author{
	 char AuthorCode[7];
	 char AuthorName[21];
	 char AuthorAddress[21];
};

struct Author author;

struct AuthorRefer{
	 char AuthorCode[7];
	 char AuthorName[21];
	 struct  AuthorRefer *authorlink;
};
struct AuthorRefer *myauthorrefer;
/*============================declare structure================================================== =*/
int main()
{
	 myauthorrefer=(struct AuthorRefer*)malloc(sizeof(struct AuthorRefer));
	 LoadAuthorRecord(&myauthorrefer);
	 bool isExit=false;
	 while (!isExit)
	 {
		DisplayAuthorMenu();
		char ch;
		gets(&ch);
		switch (ch){
			 case '1':
				  SearchByAuthorCode();
				  break;
			 case '2':
				  SearchByAuthorName();
				  break;
			 case '3':
				  AddAuthorRecord();
				  break;
			 case '4':
				  AmendAuthorRecord();
				  break;
			 case '5':
				  isExit=true;
			 }
		}
	 return 0;
} 

/*===============================author sub menu upon================================================*/
void DisplayAuthorMenu()
{
	 puts("if you want to search a author by Author code, please enter 1:");
	 puts("if you want to search a author by Author name, please enter 2:");
	 puts("if you want to add a new Author record, please enter 3:");
	 puts("if you want to amend a Author record, please enter 4:");
	 puts("if you want to shut down, please enter 5:");
}
/*======================================================*/
void OpenAuthorFile()
{
 
fAuthor=fopen("a:\\author.txt", "r+");	
if (fAuthor==0)
		{puts("author file is not existed, create one?");
                 fAuthor=fopen("a:\\author.txt", "w");
		 fclose(fAuthor);
		 fAuthor=fopen("a:\\author.txt", "r+");
		}
		 
		
}
/*===================================open author file upon================================================*/
void CloseAuthorFile()
{
			fclose(fAuthor);
}
/*=================================close author file upon=============================================*/
void SearchByAuthorCode()
{
		OpenAuthorFile();
	  puts("please enter author code for the record you want to search./n");
	  gets(SearchedAuthorCode);

		  if (SearchAuthor())     //search author code
			  {DisplaySearchedAuthorRecord();
				 CloseAuthorFile();
				 return;
			  }
		  else
			  {printf("Author code was not found, retry.");
				//puts("please enter author code for the record you want to search./n");
				//gets(SearchedAuthorCode);
				return;
				}

}
/*================================function search by author code upon===============================================*/
void DisplaySearchedAuthorRecord()
{
 long offset;
		printf("fallowing is the searched record details.");


		offset=sizeof(author)* CurrAuthorRecNum;
		fseek(fAuthor,offset,0);
		fread(&author, sizeof(author), 1, fAuthor);
		puts(author.AuthorCode);
		puts(author.AuthorName);
		puts(author.AuthorAddress);
     printf("search successful.");
}
/*================================function DisplaySearched Author Record upon===============================================*/


void AddAuthorRecord()
{

	puts("enter new Author code");
	 gets(SearchedAuthorCode);
	 OpenAuthorFile();
	while(true){
	 if (SearchAuthor()){
		  printf("record has existed in file, retry.");
        puts("enter new Author code");
		  gets(SearchedAuthorCode);
		  }
	 else {
			 if (WriteNewAuthorRecord())
				{
				 AddAuthorNode(&myauthorrefer, TotalAuthorNode);
				 fclose(fAuthor);
				 return;
				 }        
			 else
				{fclose(fAuthor);
				 return;
				}
		  }
	 }
 
}
/*=====================function add Author record upon=========================================================*/
bool WriteNewAuthorRecord()
{
	  long offset;
	  char temp_name[21];
	  char temp_address[21];
	  offset=sizeof(author)* TotalAuthorNode;
	  fseek(fAuthor, offset, 0);

	  fflush(stdin);
	  if(strlen(SearchedAuthorCode)>0 & strlen(SearchedAuthorCode)<7)
		  strcpy(author.AuthorCode, SearchedAuthorCode);
	  else
		  {puts("enterd author code is not valid, add process stop.");
			return false;
		  }

		puts("enter new value for Author name./n");
		gets(temp_name);
		if(strlen(temp_name)>0 & strlen(temp_name)<21)
			strcpy(author.AuthorName, temp_name);
		else
		   {puts("enterd author code is not valid, add process stop.");
		return false;
		  }

		puts("enter new address for Author address./n");
		gets(temp_address);
		if(strlen(temp_address)>0 & strlen(temp_address)<21)
			strcpy(author.AuthorAddress, temp_address);
		else
		   {puts("enterd author code is not valid, add process stop.");
			return false;
		  }
		fwrite(&author, sizeof(Author), 1, fAuthor);
		puts("new record is successfully added.");    
		return true;
}
/*============================function write new Author record upon==================================================*/


void AmendAuthorRecord()
{
	  
	  long offset;
	  char temp_name[21];
	  char temp_address[21];


	  fflush(stdin);
	  puts("enter  Author code for record you want to amend");
	  gets(SearchedAuthorCode);
	  OpenAuthorFile();
	  //search duplicate item
	 // while(true){
	  if (SearchAuthor()){

		  offset=sizeof(author)* CurrAuthorRecNum;
			fseek(fAuthor, offset, 0);
			fread(&author, sizeof(author), 1, fAuthor);
			puts("change record now./n");

			puts(author.AuthorName);
			puts("enter new value for Author name./n");
			gets(temp_name);
			if(strlen(temp_name)>0 & strlen(temp_name)<21)
				strcpy(author.AuthorName, temp_name);
			else
				{printf("entered author name is not valid, amend process fail.");
				return;
				}

			puts(author.AuthorAddress);
			puts("enter new value for Author address./n");
			gets(temp_address);
			if(strlen(temp_address)>0 & strlen(temp_address)<21)
				strcpy(author.AuthorAddress, temp_address);
         else
				{printf("entered author name is not valid, amend process fail.");
				return;
				}
				
			fseek(fAuthor, offset, 0);
			fwrite(&author, sizeof(author),1,fAuthor);
			fflush(stdin);

			puts("amend record successful.");
			CloseAuthorFile();
			LoadAuthorRecord(&myauthorrefer);
	  }
	  else
	  {
			printf("searched author is not exist, you have to retry.");
			fflush(stdin);
			// puts("enter  Author code for record you want to amend");
			// gets(SearchedAuthorCode);
	  }
}
/*========================function Ament Author Record upon=====================================================*/
bool SearchAuthor()
{
		 int index=0;
		 struct AuthorRefer *temp;
		 temp=myauthorrefer;
	 //fseek(fAuthor,0,0);
	  if  (TotalAuthorNode==0 )
		  { puts("file is empty.");
			 return false;
		  }
	  while (index<=TotalAuthorNode)
	  {

		  if  (strcmp(SearchedAuthorCode,temp->AuthorCode)==0)
		  {	CurrAuthorRecNum=index;
				return true;
		  }
		  else
				{index+=1;
				 temp=temp->authorlink;
				}
	  }

	  return false;
}
/*========================function search upon======================================================*/
void SearchByAuthorName()
{
	  int index=0;
	  struct AuthorRefer *temp;
	  temp=myauthorrefer;
	  

	  
while(true)
{
	  CurrAuthorRecNum=0;
     index=0;
	  puts("please enter Author name for the record you want to search./n");
	  gets(SearchedAuthorName);
	  OpenAuthorFile();
	  if (TotalAuthorNode==0)
	  { puts("not found");
		 CloseAuthorFile();
		 return;
	  }
		while (index<TotalAuthorNode)
		{
			  if   (strcmp(SearchedAuthorName, temp->AuthorName)==0)
			  {
					 CurrAuthorRecNum= index;
					 DisplaySearchedAuthorRecord();
					// index+=1;
					 temp=temp->authorlink;
					 puts("you get the result.");
			  }
			  else
			  {
					 index+=1;
					 temp=temp->authorlink;
			  }
		}
		puts("if no result display, that means searched author name is not exist.");
		CloseAuthorFile();
 }


}
/*============================function SearchByAuthorName upon==================================================*/
bool FindAuthorName()
{

	  OpenAuthorFile();


	
		return false ;

			 

}
/*===============================================================================*/


 void  LoadAuthorRecord(struct AuthorRefer **q)
{
	long offset;
	struct AuthorRefer *temp;
	temp=*q;
	TotalAuthorNode=0;
	OpenAuthorFile();


			 while(true)
			 {
				if (fread(&author, sizeof(author),1,fAuthor)==1)
				{
					 if (temp==NULL)
					 {
						temp=(struct AuthorRefer*)malloc(sizeof(struct AuthorRefer));
						AssignAuthorRefer(&temp);
					 }
					 else
					 {
						temp->authorlink=(struct AuthorRefer*)malloc(sizeof(struct AuthorRefer) );
						temp=temp->authorlink;
						AssignAuthorRefer(&temp);
					 }
				}
				else
				 {
					CloseAuthorFile();
					break;
				 }
			 }

	/*catch (const exception& e)
	{
		  cout << "Got an exception: " << e.what() << endl;
		  ClosePubFile();
	}  */
   return;
}
 
/*========================Load Author Record upon=======================================================*/
void AssignAuthorRefer(struct AuthorRefer **p)
{
	  struct AuthorRefer *temp;
	  temp=*p;

	  long offset=sizeof(author)*TotalAuthorNode;
	  fseek(fAuthor, offset, 0);
	  fread(&author, sizeof(author), 1,fAuthor);
	  strcpy(temp->AuthorCode,author.AuthorCode);
	  strcpy(temp->AuthorName, author.AuthorName);
	  TotalAuthorNode+=1;
	  return;
}
/*=======================Assign Author Refer================================*/
void AddAuthorNode(struct AuthorRefer **q, int num)
{

	  int index;
	  struct  AuthorRefer *temp;


		  if (TotalAuthorNode==0 || *q==NULL)
		  {
			  *q=(struct AuthorRefer*)malloc(sizeof(struct AuthorRefer));  
			  temp=*q;
			  AssignAuthorRefer(&temp);
			  return;
		  }
		  else
		  {
				while(index<=TotalAuthorNode)
				{
				temp=temp->authorlink;
				}
				 temp=(struct AuthorRefer*)malloc(sizeof(struct AuthorRefer) );
				 AssignAuthorRefer(&temp);

		  }
        return;
}
/*===========================================================*/

 

 
